﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SharpMUD.Framework.ComponentModel.LinearDependency
{
    public static class DependencyHelper
    {
        public static IEnumerable<Tuple<T,IEnumerable<T>>> GetAllDirectDependencies<T>(Func<T, IEnumerable<T>> GetDirectDependencies, T item)
        {
            var directDependencyMappings = new Dictionary<T, IEnumerable<T>>();

            var rootItemDependencies = GetDirectDependencies(item);
            directDependencyMappings.Add(item, rootItemDependencies);

            var unsearchedItems = new List<T>(rootItemDependencies.Except(new T [] {item}));
            while (unsearchedItems.Count() > 0)
            {
                var itemsSearchedThisRound = unsearchedItems.ToArray();
                var itemsDiscoveredThisRound = new List<T>();
                foreach (var i in itemsSearchedThisRound)
                {
                    var currentItemDependencies = GetDirectDependencies(i);
                    itemsDiscoveredThisRound.AddRange(currentItemDependencies.Where( x => !directDependencyMappings.ContainsKey(x)));
                    if (!directDependencyMappings.ContainsKey(i))
                        directDependencyMappings.Add(i,currentItemDependencies);
                }
                unsearchedItems.AddRange(itemsDiscoveredThisRound);
                unsearchedItems = unsearchedItems.Except(itemsSearchedThisRound).ToList();
            }


            //var totalDependencyMappings = new Dictionary<T,List<T>>();
            //var partialTotalDependencyMappings = new Dictionary<T,List<T>>();
            //unsearchedItems = new List<T>(directDependencyMappings.Keys);
            //while(unsearchedItems.Count()>0)
            //{
            //    unsearchedItems.ForEach( i => {
            //        var itemsDirectDependencies = directDependencyMappings[i];
            //        var itemsTotalDependencies = itemsDirectDependencies.SelectMany(j=>
            //    });
            //}
            return
                from i in directDependencyMappings.Keys
                select new Tuple<T, IEnumerable<T>>(i, directDependencyMappings[i]);
        }
    }
}
